package sim

import chisel3._
import chisel3.util._
import mycore._

class SimTop extends Module {
  val io = IO(new Bundle {
    val logCtrl = new LogCtrlIO
    val perfInfo = new PerfInfoIO
    val uart = new UARTIO

    val memAXI_0_aw_ready = Input(Bool())
    val memAXI_0_aw_valid = Output(Bool())
    val memAXI_0_aw_bits_addr = Output(UInt(64.W))
    val memAXI_0_aw_bits_prot = Output(UInt(3.W))
    val memAXI_0_aw_bits_id = Output(UInt(4.W))
    val memAXI_0_aw_bits_len = Output(UInt(8.W))
    val memAXI_0_aw_bits_size = Output(UInt(3.W))
    val memAXI_0_aw_bits_burst = Output(UInt(2.W))
    val memAXI_0_aw_bits_lock = Output(Bool())
    val memAXI_0_aw_bits_cache = Output(UInt(4.W))
    val memAXI_0_aw_bits_qos = Output(UInt(4.W))

    val memAXI_0_w_ready = Input(Bool())
    val memAXI_0_w_valid = Output(Bool())
    val memAXI_0_w_bits_data = Output(UInt(64.W))
    val memAXI_0_w_bits_strb = Output(UInt(8.W))
    val memAXI_0_w_bits_last = Output(Bool())

    val memAXI_0_b_ready = Output(Bool())
    val memAXI_0_b_valid = Input(Bool())
    val memAXI_0_b_bits_resp  = Input(Bool())
    val memAXI_0_b_bits_id  = Input(Bool())

    val memAXI_0_ar_ready = Input(Bool())
    val memAXI_0_ar_valid = Output(Bool())
    val memAXI_0_ar_bits_addr = Output(UInt(64.W))
    val memAXI_0_ar_bits_prot = Output(UInt(3.W))
    val memAXI_0_ar_bits_id = Output(UInt(4.W))
    val memAXI_0_ar_bits_len = Output(UInt(8.W))
    val memAXI_0_ar_bits_size = Output(UInt(3.W))
    val memAXI_0_ar_bits_burst = Output(UInt(2.W))
    val memAXI_0_ar_bits_lock = Output(Bool())
    val memAXI_0_ar_bits_cache = Output(UInt(4.W))
    val memAXI_0_ar_bits_qos = Output(UInt(4.W))

    val memAXI_0_r_ready = Output(Bool())
    val memAXI_0_r_valid = Input(Bool())
    val memAXI_0_r_bits_resp = Input(UInt(2.W))
    val memAXI_0_r_bits_data = Input(UInt(64.W))
    val memAXI_0_r_bits_last = Input(Bool())
    val memAXI_0_r_bits_id = Input(UInt(4.W))
  })

  val AbstractCore = Module(new AbstractCore)
  val AXICare = Module(new AXICare)

  AbstractCore.io.TIME <> AXICare.io.TIME
  AbstractCore.io.ramhelperIO <> AXICare.io.ramhelperIO

  AbstractCore.io.isSoC := false.B
  AXICare.io.isSoC := false.B

  /*
      AXI Care + AXI Const = AXI Full
  */
  io.memAXI_0_aw_ready <> AXICare.io.MYAXI.AWREADY
  io.memAXI_0_aw_valid <> AXICare.io.MYAXI.AWVALID
  io.memAXI_0_aw_bits_addr <> AXICare.io.MYAXI.AWADDR
  io.memAXI_0_aw_bits_size <> AXICare.io.MYAXI.AWSIZE
  io.memAXI_0_aw_bits_prot <> 0.U
  io.memAXI_0_aw_bits_id <> 0.U
  io.memAXI_0_aw_bits_len <> 0.U
  io.memAXI_0_aw_bits_burst <> 1.U
  io.memAXI_0_aw_bits_lock <> false.B
  io.memAXI_0_aw_bits_cache <> 0.U
  io.memAXI_0_aw_bits_qos <> 0.U

  io.memAXI_0_w_ready <> AXICare.io.MYAXI.WREADY
  io.memAXI_0_w_valid <> AXICare.io.MYAXI.WVALID
  io.memAXI_0_w_bits_data <> AXICare.io.MYAXI.WDATA
  io.memAXI_0_w_bits_strb <> AXICare.io.MYAXI.WSTRB
  io.memAXI_0_w_bits_last <> 1.U

  io.memAXI_0_b_ready <> AXICare.io.MYAXI.BREADY
  io.memAXI_0_b_valid <> AXICare.io.MYAXI.BVALID
  //io.memAXI_0_b_bits_resp
  //io.memAXI_0_b_bits_id

  io.memAXI_0_ar_ready <> AXICare.io.MYAXI.ARREADY
  io.memAXI_0_ar_valid <> AXICare.io.MYAXI.ARVALID
  io.memAXI_0_ar_bits_addr <> AXICare.io.MYAXI.ARADDR
  io.memAXI_0_ar_bits_size <> AXICare.io.MYAXI.ARSIZE
  io.memAXI_0_ar_bits_prot <> 0.U
  io.memAXI_0_ar_bits_id <> 0.U
  io.memAXI_0_ar_bits_len <> 0.U
  io.memAXI_0_ar_bits_burst <> 1.U
  io.memAXI_0_ar_bits_lock <> 0.U
  io.memAXI_0_ar_bits_cache <> 0.U
  io.memAXI_0_ar_bits_qos <> 0.U

  io.memAXI_0_r_ready <> AXICare.io.MYAXI.RREADY
  io.memAXI_0_r_valid <> AXICare.io.MYAXI.RVALID
  io.memAXI_0_r_bits_data <> AXICare.io.MYAXI.RDATA
  //io.memAXI_0_r_bits_resp 
  //io.memAXI_0_r_bits_last
  //io.memAXI_0_r_bits_id



  val InstrCommit = Module(new DifftestInstrCommit)
  val ArchIntRegState = Module(new DifftestArchIntRegState)
  val CSRState = Module(new DifftestCSRState)
  val TrapEvent = Module(new DifftestTrapEvent)
  val ArchFpRegState = Module(new DifftestArchFpRegState)
  val ArchEvent = Module(new DifftestArchEvent)

  AbstractCore.io.InstrCommit <> InstrCommit.io
  AbstractCore.io.ArchIntRegState <> ArchIntRegState.io
  AbstractCore.io.CSRState <> CSRState.io
  AbstractCore.io.TrapEvent <> TrapEvent.io
  AbstractCore.io.ArchFpRegState <> ArchFpRegState.io
  AbstractCore.io.ArchEvent <> ArchEvent.io

  io.uart.in.valid := false.B
  io.uart.out.valid := false.B
  io.uart.out.ch := 0.U
}